package ink.ykb.demo.permission.service;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ink.ykb.demo.config.CodeConstant;
import ink.ykb.demo.config.MessageUtil;
import ink.ykb.demo.config.ServiceException;
import ink.ykb.demo.permission.dao.RoleDao;
import ink.ykb.demo.permission.entity.Role;
import ink.ykb.demo.permission.entity.RoleRule;
import ink.ykb.demo.permission.entity.UserRole;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class RoleServiceImpl implements RoleService{

  @Autowired
  private MessageUtil messageUtil;
  @Autowired
  private RoleDao roleDao;
  @Autowired
  private RoleRuleService roleRuleService;
  @Autowired
  private UserRoleService userRoleService;
	@Autowired
	private ObjectMapper objectMapper;

  @Caching(evict = {
      @CacheEvict(cacheNames = {"roleList"}, allEntries=true)
  })
  @Transactional
  @Override
  public void add(Role role) {
    if(role == null) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    if(role.getName() == null) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    if(StringUtils.isBlank(role.getCode())) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    
    Role dbRole = roleDao.getRoleAndLock(role.getCode());
    if(dbRole != null) {
      throw new ServiceException(CodeConstant.MUS_102,messageUtil.getMsg(CodeConstant.MUS_102));
    }
    
    role.setCreateTime(new Date());
    roleDao.insert(role);
    
  }

  @Caching(evict = {
      @CacheEvict(cacheNames = {"role"},key = "#role.id"),
      @CacheEvict(cacheNames = {"roleList"}, allEntries=true)
  })
  @Transactional
  @Override
  public void update(Role role) {
    if(role == null) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    if(role.getId() == null) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    if(role.getName() == null) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    if(StringUtils.isBlank(role.getCode())) {
      throw new ServiceException(CodeConstant.PARAMS_EMPTY,messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
    }
    
    //判断code是否重复
    Role dbCodeRole = roleDao.getRoleAndLock(role.getCode());
    if(dbCodeRole != null && !dbCodeRole.getId().equals(role.getId())) {
      throw new ServiceException(CodeConstant.MUS_102,messageUtil.getMsg(CodeConstant.MUS_102));
    }
    
    Role dbRole = roleDao.getRoleById(role.getId());
    if(dbRole == null) {
      throw new ServiceException(CodeConstant.MUS_103,messageUtil.getMsg(CodeConstant.MUS_103));
    }
    
    dbRole.setName(role.getName());
    dbRole.setCode(role.getCode());
    
    roleDao.updateById(dbRole);
  }

  @Caching(evict = {
      @CacheEvict(cacheNames = {"role"},key = "#roleId"),
      @CacheEvict(cacheNames = {"roleList"}, allEntries=true)
  })
  @Transactional
  @Override
  public void delete(Long roleId) {
    Role dbRole = roleDao.getRoleById(roleId);
    if(dbRole == null) {
      throw new ServiceException(CodeConstant.MUS_103,messageUtil.getMsg(CodeConstant.MUS_103));
    }
    
    roleDao.deleteById(dbRole.getId());
    
    //删除角色对应的所有权限关联关系
    List<RoleRule> roleRuleList = roleRuleService.getRoleRuleListByRoleId(roleId);
    for (RoleRule roleRule : roleRuleList) {
      roleRuleService.delete(roleRule.getId());
    }
    
    //删除角色对应的所有用户关联关系
    List<UserRole> userRoleList = userRoleService.getUserRoleListByRoleId(roleId);
    for (UserRole userRole : userRoleList) {
      userRoleService.delete(userRole.getId());
    }
    
    //打印日志
  		try {
  			String dbRoleJson = objectMapper.writeValueAsString(dbRole);
  			String roleRuleListJson = objectMapper.writeValueAsString(roleRuleList);
  			String userRoleListJson = objectMapper.writeValueAsString(userRoleList);
  			log.warn("\n删除操作\n角色:{}，\n关联的权限：{}，\n关联的用户：{}",
  					dbRoleJson,roleRuleListJson,userRoleListJson);
  		} catch (JsonProcessingException e) {
  			e.printStackTrace();
  		}
  }

  @Cacheable(cacheNames = "roleList",key = "'roleList'")
  @Override
  public List<Role> getRoleList() {
    return roleDao.getRoleList();
  }

  @Cacheable(cacheNames = "role",key = "#roleId")
  @Override
  public Role getRole(Long roleId) {
    return roleDao.getRoleById(roleId);
  }
  

}
